<template>
  <div class="file-container">
    <!-- 顶部操作栏 -->
    <el-row :gutter="20" class="mb-20">
      <el-col :span="6">
        <el-select v-model="queryParams.categoryId" placeholder="选择分类" clearable @change="handleQuery">
          <el-option v-for="item in categoryOptions" :key="item.id" :label="item.name" :value="item.id" />
        </el-select>
      </el-col>
      <el-col :span="6">
        <el-select v-model="queryParams.fileType" placeholder="文件类型" clearable @change="handleQuery">
          <el-option label="图片" value="image" />
          <el-option label="文档" value="document" />
          <el-option label="视频" value="video" />
          <el-option label="音频" value="audio" />
          <el-option label="其他" value="other" />
        </el-select>
      </el-col>
      <el-col :span="6">
        <el-input v-model="queryParams.keyword" placeholder="搜索文件名" clearable @keyup.enter.native="handleQuery" />
      </el-col>
      <el-col :span="6">
        <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
        <el-button type="success" icon="el-icon-upload" @click="handleUpload">上传文件</el-button>
        <el-button type="info" icon="el-icon-folder-add" @click="handleAddCategory">新建分类</el-button>
      </el-col>
    </el-row>

    <!-- 文件统计信息 -->
    <el-row :gutter="20" class="mb-20">
      <el-col :span="6" v-for="(value, key) in fileStats.typeStats" :key="key">
        <el-card shadow="hover" class="stat-card">
          <div class="stat-content">
            <div class="stat-title">{{ getFileTypeLabel(key) }}</div>
            <div class="stat-value">{{ value }} 个文件</div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card shadow="hover" class="stat-card">
          <div class="stat-content">
            <div class="stat-title">总文件数</div>
            <div class="stat-value">{{ fileStats.totalCount || 0 }}</div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card shadow="hover" class="stat-card">
          <div class="stat-content">
            <div class="stat-title">总容量</div>
            <div class="stat-value">{{ formatFileSize(fileStats.totalSize) }}</div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 文件列表 -->
    <el-tabs v-model="viewMode" @tab-click="handleViewModeChange">
      <el-tab-pane label="卡片视图" name="card">
        <el-row :gutter="20">
          <el-col :span="6" v-for="item in fileList" :key="item.id" class="mb-20">
            <el-card shadow="hover" class="file-card" :body-style="{ padding: '10px' }">
              <div class="file-preview" @click="handlePreview(item)">
                <!-- 图片预览 -->
                <img v-if="isImageFile(item.fileType)" :src="item.thumbnailUrl || item.fileUrl" class="image-preview">
                <!-- 其他文件图标 -->
                <div v-else class="file-icon">
                  <i :class="getFileIcon(item.fileType)"></i>
                </div>
              </div>
              <div class="file-info">
                <div class="file-name" :title="item.originalName">{{ item.originalName }}</div>
                <div class="file-meta">
                  <span>{{ formatFileSize(item.fileSize) }}</span>
                  <span>{{ formatDate(item.createTime) }}</span>
                </div>
                <div class="file-actions">
                  <el-button type="text" icon="el-icon-download" @click="handleDownload(item)">下载</el-button>
                  <el-button type="text" icon="el-icon-edit" @click="handleEdit(item)">编辑</el-button>
                  <el-button type="text" icon="el-icon-delete" @click="handleDelete(item)">删除</el-button>
                </div>
              </div>
            </el-card>
          </el-col>
        </el-row>
      </el-tab-pane>
      <el-tab-pane label="列表视图" name="list">
        <el-table :data="fileList" style="width: 100%" border>
          <el-table-column type="selection" width="55"></el-table-column>
          <el-table-column label="文件名" prop="originalName" min-width="200"></el-table-column>
          <el-table-column label="类型" width="120">
            <template slot-scope="scope">
              {{ getFileTypeLabel(getSimpleFileType(scope.row.fileType)) }}
            </template>
          </el-table-column>
          <el-table-column label="大小" width="120">
            <template slot-scope="scope">
              {{ formatFileSize(scope.row.fileSize) }}
            </template>
          </el-table-column>
          <el-table-column label="分类" width="120" prop="categoryName"></el-table-column>
          <el-table-column label="上传时间" width="180">
            <template slot-scope="scope">
              {{ formatDate(scope.row.createTime) }}
            </template>
          </el-table-column>
          <el-table-column label="操作" width="220">
            <template slot-scope="scope">
              <el-button type="text" icon="el-icon-view" @click="handlePreview(scope.row)">预览</el-button>
              <el-button type="text" icon="el-icon-download" @click="handleDownload(scope.row)">下载</el-button>
              <el-button type="text" icon="el-icon-edit" @click="handleEdit(scope.row)">编辑</el-button>
              <el-button type="text" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-tab-pane>
    </el-tabs>

    <!-- 批量操作工具栏 -->
    <div class="batch-actions" v-if="viewMode === 'list'">
      <el-button type="danger" icon="el-icon-delete" :disabled="selectedFiles.length === 0" @click="handleBatchDelete">批量删除</el-button>
    </div>

    <!-- 上传文件对话框 -->
    <el-dialog title="上传文件" :visible.sync="uploadDialogVisible" width="500px">
      <el-form :model="uploadForm" label-width="80px">
        <el-form-item label="文件分类">
          <el-select v-model="uploadForm.categoryId" placeholder="选择分类" style="width: 100%">
            <el-option v-for="item in categoryOptions" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="公开访问">
          <el-switch v-model="uploadForm.isPublic" :active-value="1" :inactive-value="0"></el-switch>
        </el-form-item>
        <el-form-item label="上传文件">
          <el-upload
            ref="upload"
            class="upload-demo"
            :action="uploadUrl"
            :headers="uploadHeaders"
            :data="uploadData"
            :multiple="true"
            :limit="10"
            :file-list="uploadFileList"
            :on-success="handleUploadSuccess"
            :on-error="handleUploadError"
            :before-upload="beforeUpload"
            :on-exceed="handleExceed"
            :on-remove="handleRemove">
            <el-button size="small" type="primary">点击上传</el-button>
            <div slot="tip" class="el-upload__tip">支持各种类型文件，图片不超过10MB，视频不超过100MB</div>
          </el-upload>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="uploadDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="submitUpload">确 定</el-button>
      </div>
    </el-dialog>

    <!-- 编辑文件对话框 -->
    <el-dialog title="编辑文件信息" :visible.sync="editDialogVisible" width="500px">
      <el-form :model="editForm" label-width="80px">
        <el-form-item label="文件名">
          <el-input v-model="editForm.originalName"></el-input>
        </el-form-item>
        <el-form-item label="文件分类">
          <el-select v-model="editForm.categoryId" placeholder="选择分类" style="width: 100%">
            <el-option v-for="item in categoryOptions" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="公开访问">
          <el-switch v-model="editForm.isPublic" :active-value="1" :inactive-value="0"></el-switch>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="editDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="submitEdit">确 定</el-button>
      </div>
    </el-dialog>

    <!-- 添加分类对话框 -->
    <el-dialog title="添加分类" :visible.sync="categoryDialogVisible" width="500px">
      <el-form :model="categoryForm" label-width="80px">
        <el-form-item label="分类名称">
          <el-input v-model="categoryForm.name"></el-input>
        </el-form-item>
        <el-form-item label="排序">
          <el-input-number v-model="categoryForm.sort" :min="0" :max="999"></el-input-number>
        </el-form-item>
        <el-form-item label="图标">
          <el-input v-model="categoryForm.icon" placeholder="图标类名，如：el-icon-folder"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="categoryDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="submitCategory">确 定</el-button>
      </div>
    </el-dialog>

    <!-- 预览对话框 -->
    <el-dialog title="文件预览" :visible.sync="previewDialogVisible" width="80%">
      <div class="preview-container" v-if="currentFile">
        <!-- 图片预览 -->
        <img v-if="isImageFile(currentFile.fileType)" :src="getPreviewUrl(currentFile.id)" class="preview-image">
        
        <!-- PDF预览 -->
        <iframe v-else-if="isPdfFile(currentFile.fileType)" :src="getPreviewUrl(currentFile.id)" class="preview-iframe"></iframe>
        
        <!-- 视频预览 -->
        <video v-else-if="isVideoFile(currentFile.fileType)" :src="getPreviewUrl(currentFile.id)" controls class="preview-video"></video>
        
        <!-- 音频预览 -->
        <audio v-else-if="isAudioFile(currentFile.fileType)" :src="getPreviewUrl(currentFile.id)" controls class="preview-audio"></audio>
        
        <!-- 其他文件 -->
        <div v-else class="preview-other">
          <i :class="getFileIcon(currentFile.fileType)" class="preview-icon"></i>
          <div class="preview-filename">{{ currentFile.originalName }}</div>
          <el-button type="primary" @click="handleDownload(currentFile)">下载文件</el-button>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { getCategoryList, addCategory, updateCategory, deleteCategory, 
         getFileList, getFileInfo, updateFileInfo, deleteFile, batchDeleteFiles, 
         getFileStats, getUploadUrl, getDownloadUrl, getPreviewUrl } from '@/api/file'
import { getToken } from '@/utils/auth'

export default {
  name: 'FileManagement',
  data() {
    return {
      // 查询参数
      queryParams: {
        categoryId: null,
        fileType: null,
        keyword: null
      },
      // 文件列表
      fileList: [],
      // 分类选项
      categoryOptions: [],
      // 文件统计
      fileStats: {
        totalCount: 0,
        totalSize: 0,
        typeStats: {}
      },
      // 选中的文件
      selectedFiles: [],
      // 视图模式：card/list
      viewMode: 'card',
      
      // 上传对话框
      uploadDialogVisible: false,
      uploadForm: {
        categoryId: null,
        isPublic: 0
      },
      uploadUrl: getUploadUrl(),
      uploadHeaders: {
        Authorization: 'Bearer ' + getToken()
      },
      uploadData: {},
      uploadFileList: [],
      
      // 编辑对话框
      editDialogVisible: false,
      editForm: {
        id: null,
        originalName: '',
        categoryId: null,
        isPublic: 0
      },
      
      // 分类对话框
      categoryDialogVisible: false,
      categoryForm: {
        name: '',
        sort: 0,
        icon: ''
      },
      
      // 预览对话框
      previewDialogVisible: false,
      currentFile: null
    }
  },
  created() {
    this.loadCategoryOptions()
    this.loadFileStats()
    this.loadFileList()
  },
  methods: {
    // 加载文件列表
    loadFileList() {
      getFileList(this.queryParams).then(response => {
        this.fileList = response.data
      })
    },
    
    // 加载分类选项
    loadCategoryOptions() {
      getCategoryList().then(response => {
        this.categoryOptions = response.data
      })
    },
    
    // 加载文件统计
    loadFileStats() {
      getFileStats().then(response => {
        this.fileStats = response.data
      })
    },
    
    // 处理查询
    handleQuery() {
      this.loadFileList()
    },
    
    // 处理上传
    handleUpload() {
      this.uploadDialogVisible = true
      this.uploadForm = {
        categoryId: null,
        isPublic: 0
      }
      this.uploadFileList = []
      this.uploadData = {
        isPublic: 0
      }
    },
    
    // 处理添加分类
    handleAddCategory() {
      this.categoryDialogVisible = true
      this.categoryForm = {
        name: '',
        sort: 0,
        icon: ''
      }
    },
    
    // 提交分类
    submitCategory() {
      addCategory(this.categoryForm).then(() => {
        this.$message.success('添加分类成功')
        this.categoryDialogVisible = false
        this.loadCategoryOptions()
      })
    },
    
    // 处理视图模式切换
    handleViewModeChange() {
      // 切换视图模式时清空选中项
      this.selectedFiles = []
    },
    
    // 处理预览
    handlePreview(file) {
      this.currentFile = file
      this.previewDialogVisible = true
    },
    
    // 处理下载
    handleDownload(file) {
      window.open(getDownloadUrl(file.id))
    },
    
    // 处理编辑
    handleEdit(file) {
      this.editForm = {
        id: file.id,
        originalName: file.originalName,
        categoryId: file.categoryId,
        isPublic: file.isPublic
      }
      this.editDialogVisible = true
    },
    
    // 提交编辑
    submitEdit() {
      updateFileInfo(this.editForm).then(() => {
        this.$message.success('更新文件信息成功')
        this.editDialogVisible = false
        this.loadFileList()
      })
    },
    
    // 处理删除
    handleDelete(file) {
      this.$confirm('确认删除该文件?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        deleteFile(file.id).then(() => {
          this.$message.success('删除成功')
          this.loadFileList()
          this.loadFileStats()
        })
      })
    },
    
    // 处理批量删除
    handleBatchDelete() {
      if (this.selectedFiles.length === 0) {
        this.$message.warning('请选择要删除的文件')
        return
      }
      
      this.$confirm(`确认删除选中的${this.selectedFiles.length}个文件?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        const ids = this.selectedFiles.map(item => item.id)
        batchDeleteFiles(ids).then(response => {
          this.$message.success(`成功删除${response.data.length}个文件`)
          this.loadFileList()
          this.loadFileStats()
          this.selectedFiles = []
        })
      })
    },
    
    // 上传前检查
    beforeUpload(file) {
      // 更新上传参数
      this.uploadData = {
        categoryId: this.uploadForm.categoryId,
        isPublic: this.uploadForm.isPublic
      }
      return true
    },
    
    // 上传成功处理
    handleUploadSuccess(response, file, fileList) {
      this.$message.success('上传成功')
    },
    
    // 上传错误处理
    handleUploadError(err, file, fileList) {
      this.$message.error('上传失败: ' + err.message)
    },
    
    // 处理超出上传数量限制
    handleExceed() {
      this.$message.warning('最多一次上传10个文件')
    },
    
    // 处理移除上传文件
    handleRemove(file, fileList) {
      this.uploadFileList = fileList
    },
    
    // 提交上传
    submitUpload() {
      this.$refs.upload.submit()
      this.uploadDialogVisible = false
      // 延迟刷新列表
      setTimeout(() => {
        this.loadFileList()
        this.loadFileStats()
      }, 1000)
    },
    
    // 格式化文件大小
    formatFileSize(size) {
      if (!size) return '0 B'
      
      const units = ['B', 'KB', 'MB', 'GB', 'TB']
      let index = 0
      let fileSize = size
      
      while (fileSize >= 1024 && index < units.length - 1) {
        fileSize /= 1024
        index++
      }
      
      return fileSize.toFixed(2) + ' ' + units[index]
    },
    
    // 格式化日期
    formatDate(date) {
      if (!date) return ''
      const d = new Date(date)
      return d.toLocaleString()
    },
    
    // 判断是否为图片文件
    isImageFile(contentType) {
      return contentType && contentType.startsWith('image/')
    },
    
    // 判断是否为PDF文件
    isPdfFile(contentType) {
      return contentType && contentType.includes('pdf')
    },
    
    // 判断是否为视频文件
    isVideoFile(contentType) {
      return contentType && contentType.startsWith('video/')
    },
    
    // 判断是否为音频文件
    isAudioFile(contentType) {
      return contentType && contentType.startsWith('audio/')
    },
    
    // 获取文件图标
    getFileIcon(contentType) {
      if (!contentType) return 'el-icon-document'
      
      if (contentType.startsWith('image/')) {
        return 'el-icon-picture'
      } else if (contentType.includes('pdf')) {
        return 'el-icon-document-checked'
      } else if (contentType.includes('word') || contentType.includes('document')) {
        return 'el-icon-document-word'
      } else if (contentType.includes('excel') || contentType.includes('spreadsheet')) {
        return 'el-icon-document-excel'
      } else if (contentType.includes('powerpoint') || contentType.includes('presentation')) {
        return 'el-icon-document-powerpoint'
      } else if (contentType.startsWith('video/')) {
        return 'el-icon-video-camera'
      } else if (contentType.startsWith('audio/')) {
        return 'el-icon-headset'
      } else if (contentType.includes('zip') || contentType.includes('compressed')) {
        return 'el-icon-folder-zip'
      } else {
        return 'el-icon-document'
      }
    },
    
    // 获取简化的文件类型
    getSimpleFileType(contentType) {
      if (!contentType) return 'other'
      
      if (contentType.startsWith('image/')) {
        return 'image'
      } else if (contentType.startsWith('video/')) {
        return 'video'
      } else if (contentType.startsWith('audio/')) {
        return 'audio'
      } else if (contentType.includes('pdf') || contentType.includes('document') || 
              contentType.includes('msword') || contentType.includes('officedocument')) {
        return 'document'
      } else {
        return 'other'
      }
    },
    
    // 获取文件类型标签
    getFileTypeLabel(type) {
      const labels = {
        'image': '图片',
        'video': '视频',
        'audio': '音频',
        'document': '文档',
        'other': '其他'
      }
      return labels[type] || '未知'
    },
    
    // 获取预览URL
    getPreviewUrl(id) {
      const token = getToken()
      return `${getPreviewUrl(id)}?token=${token}`
    }
  }
}
</script>

<style lang="scss" scoped>
.file-container {
  padding: 20px;
}

.mb-20 {
  margin-bottom: 20px;
}

.stat-card {
  height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
  
  .stat-content {
    text-align: center;
    
    .stat-title {
      font-size: 14px;
      color: #606266;
    }
    
    .stat-value {
      font-size: 24px;
      font-weight: bold;
      margin-top: 10px;
    }
  }
}

.file-card {
  height: 220px;
  
  .file-preview {
    height: 120px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    overflow: hidden;
    
    .image-preview {
      max-width: 100%;
      max-height: 100%;
      object-fit: contain;
    }
    
    .file-icon {
      font-size: 50px;
      color: #909399;
    }
  }
  
  .file-info {
    margin-top: 10px;
    
    .file-name {
      font-size: 14px;
      font-weight: bold;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    
    .file-meta {
      font-size: 12px;
      color: #909399;
      margin: 5px 0;
      
      span {
        margin-right: 10px;
      }
    }
    
    .file-actions {
      margin-top: 5px;
      
      .el-button {
        padding: 0 5px;
      }
    }
  }
}

.batch-actions {
  margin-top: 20px;
  padding: 10px 0;
  border-top: 1px solid #ebeef5;
}

.preview-container {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 400px;
  
  .preview-image {
    max-width: 100%;
    max-height: 600px;
  }
  
  .preview-iframe {
    width: 100%;
    height: 600px;
    border: none;
  }
  
  .preview-video {
    max-width: 100%;
    max-height: 600px;
  }
  
  .preview-audio {
    width: 100%;
  }
  
  .preview-other {
    text-align: center;
    
    .preview-icon {
      font-size: 80px;
      color: #909399;
    }
    
    .preview-filename {
      margin: 20px 0;
      font-size: 16px;
    }
  }
}
</style> 